/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: DELL
 * Date: 2022-08-14
 * Time: 16:47
 */
class Animal2 {
    public String name;
    public int ange;

    public Animal2(String name, int ange) {
        this.name = name;
        this.ange = ange;
    }

    public void eat() {
        System.out.println(name + " 在吃饭");
    }
}

class Tiger extends Animal2 {

    public Tiger(String name, int ange) {
        super(name, ange);
    }

    @Override
    //子类在重写父类方法时，方法名和参数都必须一致，返回类型可以不一致
    //重写的方法的访问权限必须向上访问，即访问权限必须比父类的方法权限大 public 》 protected 》 default 》 private
    public void eat() {
        System.out.println(name + " 在吃肉");
    }

    public void growl(){
        System.out.println(name+" 咆哮");
    }
}

class Wolf extends Animal2 {
    public Wolf(String name, int ange) {
        super(name, ange);
    }

    @Override
    //父类中被static private 修饰的方法和构造方法都无法被重写
    //重写只发生在继承中，必须具备继承关系
    public void eat() {
        System.out.println(name + " 在吃羊");
    }

    public void catchSheep(){
        System.out.println(name+" 在抓羊");
    }
}

public class Test_0814 {

    //通过父类的引用调用重写方法，类型为父类即 Animal2 类
    public static void eat(Animal2 a) {
        //方法写在类的内部
        a.eat();
    }

    public static void eatfood(Animal2 a){
        //向上转型--方法传参--形参作为父类型引用，可以直接接收任意子类的对象
        a.eat();
    }

    //向上转型--作为返回值--返回任意子类对象
    public static Animal2 buyAnimal2(String ret){
        if("老虎"==ret){
            return new Tiger("老虎",18);
        }else if("狼"==ret){
            return new Wolf("狼",20);
        }else {
            return null;
        }
    }

    public static void main(String[] args) {

        //具体完成某个动作当不同的对象去完成时会产生出不同的状态
        //1.必须在继承体系下
        //2.子类必须要对父类中的方法进行重写
        //3.通过父类的引用调用重写方法
/*        Tiger tiger = new Tiger("猛虎王", 10);
        Wolf wolf = new Wolf("灰太狼", 20);*/

/*      wolf.eat();
        tiger.eat();
        System.out.println("===========");

        eat(tiger);
        eat(wolf);
        System.out.println("===========");*/

        //向上转型实际就是创建一个子类对象，将其当成父类对象来使用
/*        Animal2 elephant = new Tiger("大象也可以是老虎",30);  //父类类型 对象名 = new 子类类型()

        Animal2 wolf2 = new Wolf("灰太狼表弟",3);

        eat(elephant);
        // elephant 是一个父类类型，但可以引用一个子类对象，范围是从小到大转换的
        System.out.println("============");
        //向上转型--直接赋值--子类对象直接赋值给父类
        Animal2 tiger1 = new Tiger("猛虎王弟弟",5);
        tiger1.eat();
        System.out.println("============");
        Animal2 animal2 = buyAnimal2("狼");
        animal2.eat();
        System.out.println("============");
        animal2 = buyAnimal2("老虎");
        animal2.eat();
        System.out.println("============");
        eatfood(wolf);
        eatfood(elephant);
        wolf.catchSheep(); //子类自己创建的对象可以访问子类自己独有的方法
        //wolf2.catchSheep();//向上转型缺陷--不能调用到子类特有的方法，已经转为父类类型了*/


        Tiger tiger = new Tiger("猛虎王",20);
        Wolf wolf = new Wolf("灰太狼",10);
        //向上转型

        if(tiger instanceof Tiger){
            System.out.println("3");
        }
        if(wolf instanceof Wolf){
            System.out.println("4");
        }

        if(wolf instanceof Animal2){
            System.out.println("5");
        }

        Animal2 animal2 = tiger;
        animal2.eat();
        animal2 = wolf;
        animal2.eat();//现在animal2 实际类型为Wolf类

        //向下转型 -- 引用一个父类对象还原为一个子类对象--从大范围转为小范围
/*        tiger = (Tiger) animal2;
        tiger.growl();*/

        //wolf = (Wolf) animal2; //原本指向狼类，向下转型也可以、

        //向下转型为了安全引入了类型比较运算符 instanceof
        //面对具体的子类型，向下转型具有风险。即容易发生ClassCastException(强制类型转换错误)

        if(animal2 instanceof Tiger){
            tiger = (Tiger) animal2;
            System.out.println("1");
            //instanceof 左侧类为右侧类的子类或者同类返回true，不一致返回false
        }
        if(animal2 instanceof Wolf){
            wolf = (Wolf) animal2;
            System.out.println("2");

        }
    }

}
